package org.bjf.springboot.exception;

import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.bjf.springboot.exception.CommMsgCode.DB_ERROR;
import static org.bjf.springboot.exception.CommMsgCode.OTHER_ERROR;
import static org.bjf.springboot.exception.CommMsgCode.PARAM_ERROR;

import java.sql.SQLException;
import javax.annotation.Resource;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.bjf.springboot.service.EmailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.TypeMismatchException;
import org.springframework.dao.DataAccessException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * Created by binjinfeng on 2017/5/18.
 */

@RestControllerAdvice
public class ExceptionAdvice {

  private static final Logger log = LoggerFactory.getLogger(ExceptionAdvice.class);
  @Resource
  private EmailService emailService;

  @ExceptionHandler(value = Exception.class)
  public ErrorResp onException(Exception e) {
    log.error(e.getMessage(), e);

    if (e instanceof DaoException || e instanceof SQLException
        || e instanceof DataAccessException) {
      return createErrorResp(DB_ERROR, null);
    } else if (e instanceof FatalException) {
      FatalException ex = (FatalException) e;

      emailService.asyncMail("系统错误", ExceptionUtils.getStackTrace(ex));
      return createErrorResp(ex.getMsgCode(), ex.getMessage());
    } else if (e instanceof BaseException) {
      BaseException ex = (BaseException) e;
      return createErrorResp(ex.getMsgCode(), ex.getMessage());
    } else if (e instanceof MissingServletRequestParameterException
        || e instanceof BindException
        || e instanceof TypeMismatchException
        || e instanceof ServletRequestBindingException) {
      return createErrorResp(PARAM_ERROR, "请求参数错误");
    } else {
      return createErrorResp(OTHER_ERROR, "服务器错误");
    }
  }

  private ErrorResp createErrorResp(MsgCode msgCode, String message) {
    return new ErrorResp(msgCode.getCode(),
        isNotBlank(message) ? message : msgCode.getMessage());
  }


  private class ErrorResp {

    private int code;
    private String message;

    public ErrorResp(int code, String message) {
      this.code = code;
      this.message = message;
    }

    public int getCode() {
      return code;
    }

    public void setCode(int code) {
      this.code = code;
    }

    public String getMessage() {
      return message;
    }

    public void setMessage(String message) {
      this.message = message;
    }
  }


}
